/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hu.bme.j2ee.v37zen.web.beans;

import hu.bme.j2ee.v37zen.beans.DialManagerBean;
import hu.bme.j2ee.v37zen.beans.FindUsersBean;
import hu.bme.j2ee.v37zen.entities.Dial;
import hu.bme.j2ee.v37zen.entities.User;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Principal;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.application.Resource;
import javax.faces.application.ResourceHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.component.UIPanel;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.view.facelets.FaceletContext;

/**
 *
 * @author Kiss Dániel
 */
@ManagedBean
@ViewScoped
@RolesAllowed({"USER","ADMIN"})
public class SpeedDialController implements Serializable{
    private static final long serialVersionUID = 8204827822375993146L;
        
    @EJB
    private DialManagerBean dmb;
    @EJB
    private FindUsersBean fub;
        
    private HtmlPanelGrid dialGrid;
    
    private String newURL = "http://";
    
    //private long deletedDialID;
    private String gridId = "grid-id";
    
    private User user;
            
    /**
     * Creates a new instance of SpeedDialController
     */
    public SpeedDialController() {
        
        
    }

       
    

    public String getGridId() {
        return gridId;
    }

    public void setGridId(String gridid) {
        this.gridId = gridid;
    }

    public String getNewURL() {
        return newURL;
    }

    public void setNewURL(String newURL) {
        this.newURL = newURL;
    }

    
    public void validateURL(FacesContext context, UIComponent toValidate, Object value){
        String urlString = (String)value; 
        if ( urlString.isEmpty() || urlString.equalsIgnoreCase("http://")) 
        {
            ((UIInput)toValidate).setValid(false);
            FacesMessage message = new FacesMessage("A mezőt kötelező kitölteni!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(toValidate.getClientId(context), message);
        } else {
            try {
                URL url = new URL(urlString);
            } catch (MalformedURLException ex) {
                ((UIInput)toValidate).setValid(false);
                FacesMessage message = new FacesMessage("Az URL nem jólformált!");
                message.setSeverity(FacesMessage.SEVERITY_ERROR);
                context.addMessage(toValidate.getClientId(context), message);
                return;
            }
            
            FacesMessage message = new FacesMessage("OK");
            message.setSeverity(FacesMessage.SEVERITY_INFO);
            context.addMessage(toValidate.getClientId(context), message);
        }
    }

    private User getUser(){
        if(this.user == null){
            
        
            Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
            if (principal != null) {
                this.user = fub.findUserByUsernameEager(principal.getName());
            } else {
                try {
                    FacesContext.getCurrentInstance().getExternalContext().redirect("error.xhtml");
                    return null;
                } catch (IOException ex) {
                    Logger.getLogger(SpeedDialController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return this.user;
    }

    public HtmlPanelGrid getDialGrid() {
        this.generateSpeedDial();
        return dialGrid;
    }
    
    private void generateSpeedDial(){
        if(this.dialGrid == null){
            this.dialGrid = new HtmlPanelGrid();
        }
        
        List<Dial> dials = getUser().getDials();
        
        //System.out.println("[SD-web ] [Grid Build] " + getUser().toString());
        
        for(Dial d : dials){
            UIComponent dial = this.createCompositeComponent(dialGrid, "dial-comp", "dial-comp-id" + 
                    Long.toString(d.getId()));
            
            String title = d.getTitle();
            String image = d.getFile();
            title = (title == null) ? d.getUrl().toString() : title;
            image = (image == null) ? "" : image;
            
            dial.getAttributes().put("title", title);
            dial.getAttributes().put("image", image);
            dial.getAttributes().put("url", d.getUrl());
            dial.getAttributes().put("dialid", d.getId());
            
        }        
        UIComponent dial = this.createCompositeComponent(dialGrid, "empty-dial-comp", "empty-dial-comp-id");
        
    }

    public void setDialGrid(HtmlPanelGrid dialGrid) {
        this.dialGrid = dialGrid;
    }

    
    public String navigateToAdd() {
        
        return "add-dial.xhtml";
    }
    
    public String submitAddDial() {
        try {
            User usr = getUser();
            //System.out.println("[SD-web] " + usr.toString());
            dmb.createAndAddDial(usr, new URL(this.newURL));
            //System.out.println("[SD-web] " + usr.toString());
            
        } catch (MalformedURLException ex) {
            return "error.xhtml?faces-redirect=true";
        } finally {
            this.newURL = "http://";
        }
        return "speed-dial.xhtml?faces-redirect=true";
    }
    
    public String removeDial(){
        
        String idString = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("d-dial-id");
        long id = Long.parseLong(idString);

        this.dmb.removeDial(id);
        
        return null;
        
    }
    
    public void dialDialed(AjaxBehaviorEvent event){
        
        String idString = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("d-dial-id");
        long id = Long.parseLong(idString);
        
        this.dmb.dialDialed(id);
        
    }            
    
    private UIComponent createCompositeComponent(UIComponent parent, String name, String id){
        UIComponent composite = null;
        FacesContext context = FacesContext.getCurrentInstance();
        Application application = context.getApplication();
        FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
        
        ResourceHandler handler = application.getResourceHandler();
        Resource componentResource = handler.createResource( name + ".xhtml", "components" ) ;
        
        if( componentResource != null )
        {
            composite = application.createComponent( context, componentResource );
            composite.setId( id );
            
            UIComponent implementation = application.createComponent(UIPanel.COMPONENT_TYPE);
            implementation.setRendererType("javax.faces.Group");
            composite.getFacets().put(UIComponent.COMPOSITE_FACET_NAME, implementation);
            
            
            parent.getChildren().add(composite);
            parent.pushComponentToEL(context, composite);
            
            try {
                faceletContext.includeFacelet(implementation, componentResource.getURL());
            } catch (IOException e) {
                throw new FacesException(e);
            } finally {
                parent.popComponentFromEL(context);
            }
        }
        
        return composite;
    }
     
}
